package es.deusto.ingenieria.aike.puzzle;

import java.util.ArrayList;
import java.util.List;

import es.deusto.ingenieria.aike.search.heuristic.EvaluationFunction;
import es.deusto.ingenieria.ingenieria.search.Node;

public class ManhattanDistance extends EvaluationFunction {

	public double calculateG(Node node) {
		List<String> operatorList = new ArrayList<String>();
		currentPath(node.getParent(), operatorList);
		return operatorList.size();
	}
	
	private void currentPath(Node node, List<String> operatorNames) {
		if (node == null || node.getParent() == null) {
			return;
		} else {
			operatorNames.add(0, node.getOperator());
			currentPath(node.getParent(), operatorNames);
		}
	}

	public double calculateH(Node node) {	
		Environment env = (Environment)node.getState().getInformation();	
		Environment env2 = env.clone();
		Flag flag = env2.getFlag();
		Car car = env2.getCar().clone();
		
		int result = Math.abs(flag.getPosition()[0]-car.getY()) + Math.abs(flag.getPosition()[1]-car.getX());
		
		if (!flag.getWallSituation()[0])
		{
			if (car.getX() > flag.getPosition()[1])
			{
				if (car.getY() == flag.getPosition()[0])
				{
					result+=4;
				}
				else 
				{
					result+=3;
				}
			}
			else if (car.getX() == flag.getPosition()[1])
			{
				result+=2;
			}
		}
		else if (!flag.getWallSituation()[1])
		{
			if (car.getY() > flag.getPosition()[0])
			{
				if (car.getX() == flag.getPosition()[1])
				{
					result+=4;
				}
				else 
				{
					result+=3;
				}
			}
			else if (car.getY() == flag.getPosition()[0])
			{
				result+=2;
			}
		}
		else if (!flag.getWallSituation()[2])
		{
			if (car.getX() < flag.getPosition()[1])
			{
				if (car.getY() == flag.getPosition()[0])
				{
					result+=4;
				}
				else 
				{
					result+=3;
				}
			}
			else if (car.getX() == flag.getPosition()[1])
			{
				result+=2;
			}
		}
		else if (!flag.getWallSituation()[3])
		{
			if (car.getY() < flag.getPosition()[0])
			{
				if (car.getX() == flag.getPosition()[1])
				{
					result+=4;
				}
				else 
				{
					result+=3;
				}
			}
			else if (car.getY() == flag.getPosition()[0])
			{
				result+=2;
			}
		}
		return result;
	}
}